package com.tc.travel.submitter.executor;

import java.util.HashMap;
import java.util.Map;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.tc.travel.submitter.pojo.VisaForDownloadReturnReportDto;
import com.tc.travel.submitter.service.ReturnReportBo;
import com.tc.travel.util.Consts;
import com.tc.travel.util.HtmlUtil;
import com.tc.travel.util.HttpClientUtil;
import com.tc.travel.util.PropertyUtil;
import com.tc.travel.util.SleepUtil;
import com.tc.travel.util.StringUtil;
import com.tc.travel.util.exception.ComRuntimeException;

@Component
public class ReturnReportDownloadExecutor extends BaseExecutor {
	private static Logger log = Logger.getLogger(ReturnReportDownloadExecutor.class);

	@Autowired
	private ReturnReportBo returnReportBo;

	public void execute() {
		try {
			VisaForDownloadReturnReportDto visaDto = returnReportBo.getVisaForDownloadReturnReport();
			if (visaDto != null) {
				String cookie = sessionBo.getCookie();
				log.info("cookie:" + cookie);

				int state = Consts.RETURN_REPORT_DOWNLOAD_STATE_SUCC;
				String errorMsg = "";

				try {
					log.info("step1.openSearchVisaPage...");
					openSearchVisaPage(cookie);

					log.info("step2.getVisaIdentityId-->dest_visa_id:" + visaDto.getDestVisaId() + "...");
					SleepUtil.sleepRandom(3, 6);
					String visaIdentityId = getVisaIdentityId(visaDto.getDestVisaId(), cookie);
					log.info("visaIdentityId:" + visaIdentityId);

					log.info("step3.clickReturnReportButton...");
					SleepUtil.sleepRandom(1, 3);
					String pageKey = clickReturnReportButton(visaIdentityId, cookie);
					log.info("pageKey: " + pageKey);

					log.info("step4.clickConfirmButton...");
					SleepUtil.sleepRandom(1, 3);
					pageKey = clickConfirmButton(visaIdentityId, pageKey, cookie);
					log.info("pageKey: " + pageKey);

					log.info("step5.clickLoginButton...");
					SleepUtil.sleepRandom(1, 3);
					String uniqueKey = clickLoginButton(visaIdentityId, pageKey, cookie);
					log.info("uniqueKey: " + uniqueKey);

					log.info("step6.download pdf...");
					SleepUtil.sleepRandom(1, 3);
					String filePath = downloadPdfFile(visaDto.getVisaInfoId(), visaIdentityId, pageKey, cookie);
					log.info("filePath: " + filePath);

					log.info("step7.transfer pdf to server...");
					uploadPdfToWebServer(visaDto.getVisaInfoId(), filePath);
					log.info("filePath: " + filePath);

				} catch (Throwable e) {
					state = Consts.RETURN_REPORT_DOWNLOAD_STATE_FAIL;
					errorMsg = e.getMessage();
					log.error("download return report error. visa_info_id=" + visaDto.getVisaInfoId(), e);
				}

				log.info("updateReturnReportState:");
				returnReportBo.updateReturnReportDownloadState(visaDto.getVisaInfoId(), state, errorMsg);
			}
		} catch (Throwable e) {
			log.error("ReturnReportDownloadExecutor error: " + e.getMessage(), e);
		}
	}

	// step3. 点“归国报告”按钮
	private String clickReturnReportButton(String identityId, String cookie) {
		String url = PropertyUtil.destUrlIdentityReturnEdit;

		Map<String, String> params = new HashMap<String, String>();
		params.put("IDENTITY_ID", identityId);

		Map<String, String> headers = new HashMap<String, String>();
		headers.put("Cookie", cookie);
		headers.put("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");
		headers.put("Accept-Encoding", "gzip, deflate, sdch, br");
		headers.put("Accept-Language", "en-US,en;q=0.8,ja;q=0.6");
		headers.put("Connection", "keep-alive");
		headers.put("Host", "churenkyosystem.com");
		headers.put("Referer", "https://churenkyosystem.com/member/identity_list.php");
		headers.put("Upgrade-Insecure-Request", "1");
		headers.put("User-Agent", Consts.USER_AGENT);

		String html = HttpClientUtil.doGet(url, params, headers);
		assertConfirmPage(html);

		String pageKey = HtmlUtil.getPageKey(html);
		if (StringUtil.isEmpty(pageKey)) {
			throw new ComRuntimeException("clickReturnReportButton error; no page key found.");
		}
		return pageKey;
	}

	private void assertConfirmPage(String html) {
		if (StringUtil.isEmpty(html)) {
			throw new ComRuntimeException("clickReturnReportButton error; returned html is null.");
		}

		// if (html.indexOf("身元保証書発行内容") < 0 || html.indexOf("確認画面") < 0 || html.indexOf("査証種別") < 0) {
		// throw new ComRuntimeException("clickUploadButton error; html content error.");
		// }
	}

	// step4. 点“确认”按钮
	private String clickConfirmButton(String identityId, String pagekey, String cookie) {
		String url = PropertyUtil.destUrlIdentityReturnEdit + "?IDENTITY_ID=" + identityId;

		Map<String, String> params = new HashMap<String, String>();
		params.put("_PAGE_KEY", pagekey);
		params.put("BTN_CHECK_x", "確認");

		Map<String, String> headers = new HashMap<String, String>();
		headers.put("Cookie", cookie);
		headers.put("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");
		headers.put("Accept-Encoding", "gzip, deflate, br");
		headers.put("Accept-Language", "en-US,en;q=0.8,ja;q=0.6");
		headers.put("Cache-Control", "max-age=0");
		headers.put("Connection", "keep-alive");
		headers.put("Host", "churenkyosystem.com");
		headers.put("Origin", "https://churenkyosystem.com");
		headers.put("Referer", "https://churenkyosystem.com/member/identity_return_edit.php?IDENTITY_ID=" + identityId);
		headers.put("Upgrade-Insecure-Requests", "1");
		headers.put("User-Agent", Consts.USER_AGENT);

		String html = HttpClientUtil.doPost(url, params, headers);
		assertLoginPage(html);

		String pageKey = HtmlUtil.getPageKey(html);
		if (StringUtil.isEmpty(pageKey)) {
			throw new ComRuntimeException("clickConfirmButton error; no page key found.");
		}
		return pageKey;
	}

	private void assertLoginPage(String html) {
		if (StringUtil.isEmpty(html)) {
			throw new ComRuntimeException("clickConfirmButton error; returned html is null.");
		}

		// if (html.indexOf("身元保証書発行内容") < 0 || html.indexOf("確認画面") < 0 || html.indexOf("査証種別") < 0) {
		// throw new ComRuntimeException("clickUploadButton error; html content error.");
		// }
	}

	// step5. 点“登录”按钮
	private String clickLoginButton(String identityId, String pagekey, String cookie) {
		String url = PropertyUtil.destUrlIdentityReturnEdit + "?IDENTITY_ID=" + identityId;

		Map<String, String> params = new HashMap<String, String>();
		params.put("_PAGE_KEY", pagekey);
		params.put("BTN_CHECK_SUBMIT_x", "登 録");

		Map<String, String> headers = new HashMap<String, String>();
		headers.put("Cookie", cookie);
		headers.put("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");
		headers.put("Accept-Encoding", "gzip, deflate, br");
		headers.put("Accept-Language", "en-US,en;q=0.8,ja;q=0.6");
		headers.put("Cache-Control", "max-age=0");
		headers.put("Connection", "keep-alive");
		headers.put("Host", "churenkyosystem.com");
		headers.put("Origin", "https://churenkyosystem.com");
		headers.put("Referer", "https://churenkyosystem.com/member/identity_return_edit.php?IDENTITY_ID=" + identityId);
		headers.put("Upgrade-Insecure-Requests", "1");
		headers.put("User-Agent", Consts.USER_AGENT);

		String html = HttpClientUtil.doPost(url, params, headers);
		assertDownloadPdfPage(html);

		String uniqueKey = extractUniqueKey(html);
		if (StringUtil.isEmpty(uniqueKey)) {
			throw new ComRuntimeException("clickLoginButton error; no uniqueKey key found.");
		}
		return uniqueKey;
	}

	private String extractUniqueKey(String html) {
		String key1 = "UNIQUIE_KEY=";
		String key2 = "&IDENTITY_ID=";

		int idx1 = html.indexOf(key1);
		int idx2 = html.indexOf(key2);

		if (idx1 < 0 || idx2 < 0) {
			throw new ComRuntimeException("extractUniqueKey error; no key found.");
		}

		String uniqueKey = html.substring(idx1 + key1.length(), idx2);

		if (uniqueKey == null || uniqueKey.length() > 10) {
			throw new ComRuntimeException("extractUniqueKey error; invalid key found: " + uniqueKey);
		}

		return uniqueKey;
	}

	private void assertDownloadPdfPage(String html) {
		if (StringUtil.isEmpty(html)) {
			throw new ComRuntimeException("clickLoginButton error; returned html is null.");
		}

		// if (html.indexOf("身元保証書発行内容") < 0 || html.indexOf("確認画面") < 0 || html.indexOf("査証種別") < 0) {
		// throw new ComRuntimeException("clickUploadButton error; html content error.");
		// }
	}

	// step6. 点归国报告书展示打开pdf
	private String downloadPdfFile(Long visaInfoId, String identityId, String uniqueKey, String cookie) {
		String url = PropertyUtil.destUrlDownloadReturnReport;

		Map<String, String> params = new HashMap<String, String>();
		params.put("UNIQUIE_KEY", uniqueKey);
		params.put("IDENTITY_ID", identityId);

		Map<String, String> headers = new HashMap<String, String>();
		headers.put("Cookie", cookie);
		headers.put("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");
		headers.put("Accept-Encoding", "gzip, deflate, sdch, br");
		headers.put("Accept-Language", "en-US,en;q=0.8,ja;q=0.6");
		headers.put("Cache-Control", "max-age=0");
		headers.put("Connection", "keep-alive ");
		headers.put("Host", "churenkyosystem.com");
		headers.put("If-Modified-Since", "Mon, 11 Dec 2017 13:57:22 GMT");
		headers.put("Referer", "https://churenkyosystem.com/member/identity_return_edit.php?IDENTITY_ID=" + identityId);
		headers.put("Upgrade-Insecure-Requests", "1");
		headers.put("User-Agent", Consts.USER_AGENT);

		String fileName = visaInfoId + ".pdf";
		String filePath = HttpClientUtil.downloadFile(url, fileName, params, headers);
		return filePath;
	}

	// step7. 传回pdf
	private void uploadPdfToWebServer(Long visaInfoId, String filePath) {
		String url = PropertyUtil.interfaceUrlUploadReturnReportPdf;

		Map<String, String> params = new HashMap<String, String>();
		// params.put("fileType", Consts.FILE_TYPE_RETURN_REPORT_PDF);
		params.put("visaInfoId", visaInfoId + "");

		Map<String, String> headers = new HashMap<String, String>();

		HttpClientUtil.uploadFile(url, "returnReportPdf", filePath, params, headers);
	}

	public static void main(String[] args) {
		new ReturnReportDownloadExecutor().uploadPdfToWebServer(1271l, "C:\\travel\\tmp\\1271.pdf");
	}
}
